import React, { useEffect, useState } from 'react'
import ProgressBar from './components/ProgressBar'
// import classNames from 'classnames'
// import PropTypes from 'prop-types'
// import styles from './index.module.less'

const SIZE = 10 * 1024 * 1024 // 切片大小

const request = ({
  url,
  method = 'post',
  data,
  headers = {},
  onProgress = (e) => e,
}) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()
    xhr.upload.onprogress = onProgress
    xhr.open(method, url)
    Object.keys(headers).forEach((key) =>
      xhr.setRequestHeader(key, headers[key])
    )
    xhr.send(data)
    xhr.onload = (e) => {
      resolve({
        data: e.target.response,
      })
    }
  })
}

// 生成文件切片
const createFileChunk = (file, size = SIZE) => {
  const fileChunkList = []
  let cur = 0
  while (cur < file.size) {
    fileChunkList.push({ file: file.slice(cur, cur + size) })
    cur += size
  }
  console.log(fileChunkList)
  return fileChunkList
}

const mergeRequest = async (file) => {
  await request({
    url: '/api/merge',
    headers: {
      'content-type': 'application/json',
    },
    data: JSON.stringify({
      filename: file.name,
      size: SIZE,
    }),
  })
}

const uploadChunks = async (data, file, onProgress) => {
  const requestList = data
    .map(({ chunk, hash, index }) => {
      const formData = new FormData()
      formData.append('chunk', chunk)
      formData.append('hash', hash)
      formData.append('filename', file.name)
      return { formData, index }
    })
    .map(async ({ formData, index }) => {
      return await request({
        url: '/api/upload',
        data: formData,
        onProgress: onProgress(index),
      })
    })
  await Promise.all(requestList)
  await mergeRequest(file)
}

const Uploader = () => {
  const [file, setFile] = useState(null)
  const [data, setData] = useState([])
  const [percentage, setPercentage] = useState(0)

  const handleFileChange = (e) => {
    const [file] = e.target.files
    setFile(file)
  }

  const createProgressHandler = (index) => {
    return (e) => {
      const percentage = parseInt(String((e.loaded / e.total) * 100))
      console.log(percentage)
      setData((v) => {
        const arr = [...v]
        arr[index].percentage = percentage
        return arr
      })
    }
  }

  const handleUpload = async () => {
    if (!file) return
    const fileChunkList = createFileChunk(file)
    const data = fileChunkList.map((item, index) => ({
      chunk: item.file,
      index,
      hash: file.name + '-' + index,
      percentage: 0,
    }))
    setData(data)
    await uploadChunks(data, file, createProgressHandler)
  }

  useEffect(() => {
    if (!file || data.length === 0) {
      return
    }
    const loaded =
      data
        .map((item) => item.size * item.percentage)
        .reduce((acc, cur) => acc + cur, 0) || 0
    setPercentage(parseInt((loaded / file.size).toFixed(2)))
  }, [data, file])

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      <button onClick={handleUpload}>上传</button>
      <div>总进度：</div>
      <ProgressBar percentage={percentage} />
      <div>切片</div>
      <ol>
        {data.map((item) => (
          <li className="flex" key={item.hash}>
            <span className="mr-20">{item.hash}</span>
            <span className="mr-20">
              {(item.chunk.size / 1024 / 1024).toFixed(0)}MB
            </span>
            <ProgressBar percentage={item.percentage} />
          </li>
        ))}
      </ol>
    </div>
  )
}

export default Uploader
